home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-19 | 12.7 KB | 421 lines | [TEXT/ALFA] |
- ## -*-Tcl-*-
- # ###################################################################
- # BibTeX for MacOS -- scripts for GURL interaction with Alpha.
- #
- # FILE: "BibTeXAlphaScripts.tcl"
- # created: 13/11/96 {1:05:50 am}
- # last update: 19/11/96 {2:50:03 pm}
- # Author: Vince Darley
- # E-mail: <vince@das.harvard.edu>
- # mail: Division of Applied Sciences, Harvard University
- # Oxford Street, Cambridge MA 02138, USA
- # www: <http://www.fas.harvard.edu/~darley/>
- #
- # INSTALLATION PROCEDURE:
- #
- # Add the following line to your "prefs.tcl" (a file located in Alpha's
- # preferences folder inside your Preferences folder in your System folder):
- #
- # eventHandler GURL GURL GURLHandler
- #
- # This declares an event handler so we receive GURL events from
- # the BibTeX application (Note: do not copy the '#' at the beginning of
- # the line).
- #
- # Then move this file to the 'UserCode' folder inside the 'Tcl' folder
- # which is located in the same place as the application Alpha. Now
- # open Alpha, hit 'cmd-Y', and select 'Rebuild Tcl Indices' from the
- # menu. After a minute or so, you can quit Alpha, and installation is
- # complete.
- #
- # The only further choice you have is the value of the variable
- # Bib_AutoIndex, which you can set below.
- #
- # modified by rev reason
- # -------- --- --- -----------
- # 13/11/96 VMD 1.0 original -- for use with BibTeX 1.1.4
- # ###################################################################
- ##
-
-
- # 0=never make index (except manually)
- # 1=ask user when necessary
- # 2=always remake when necessary
- set Bib_AutoIndex 1
-
- ##
- # -------------------------------------------------------------------------
- #
- # "GURLHandler" --
- #
- # Handle general GURL events by extracting the type 'ftp', 'http',…
- # and calling a procedure ${type}GURLHandler with a single parameter
- # which is the extracted resource. Can be put to more general use.
- # -------------------------------------------------------------------------
- ##
- proc GURLHandler {msg} {
- if ![regsub {.*“(.*)”.*} $msg {\1} gurl] {
- alertnote "Didn't understand GURL: $msg"
- return
- }
- set GURLtype [lindex [split $gurl ":"] 0]
- set GURLvalue [string range $gurl [expr 1+[string length $GURLtype]] end]
- ${GURLtype}GURLHandler $GURLvalue
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bibresultGURLHandler" --
- #
- # Handle 'bibresult' GURLs, as sent by the application BibTeX. These
- # goto bibliography files, errors, warnings etc. We do the parsing here.
- # See BibTeX's readme file for the syntax of the message.
- # -------------------------------------------------------------------------
- ##
- proc bibresultGURLHandler {msg} {
- # Extract base .aux file name (full path description or 'Unknown')
- set bpos [string first ".aux:" $msg]
- set base_aux [string range $msg 0 [incr bpos 3]]
- # Get rest of message
- set msg [string range $msg [incr bpos 2] end]
- if [regsub {.*: ([^.]+.(aux|bst|bib))} $msg {\1} filename] {
- openTeXFile "$filename"
- return
- }
-
- switch [lindex [split $msg "-"] 0] {
- "Warning" {
- # extract warning type and find the entry
- # the last item is the entry (minus quotes possibly)
- set msg [string range $msg 9 end]
- set llen [llength $msg]
- set item [string trim [lindex $msg [incr llen -1]] {"}]
- set warning [lrange $msg 0 [incr llen -1]]
- if { $warning == "I didn't find a database entry for" } {
- # no entry exists, prompt to make one
- set choice [prompt \
- "No entry '$item' exists. What do you want to do?" \
- "New entry" "Choices" \
- "New entry" "New entry in new bibliography file" \
- "Add .bib file to \\bibliography\{…\}" ]
- switch $choice {
- "New entry" {
- # need to pick a .bib file
- set bibfile [bibPickBibliography 1 \
- "Select a bibliography file to which to add an entry"]
- openTeXFile $bibfile
- global entryNames
- bibFormatSetup
- newEntry [listpick -p "Which type of entry?" $entryNames]
- insertText $item
- nextTabStop
- }
- "New entry in new bibliography file" {
- set bibfile [putfile "Save new bibliography as…" ".bib"]
- if {$bibfile == ""} {
- error "No bibliography file selected."
- } else {
- new -n $bibfile
- }
- global entryNames
- bibFormatSetup
- newEntry [listpick -p "Which type of entry?" $entryNames]
- insertText $item
- nextTabStop
- }
- "Add .bib file to \\bibliography\{…\}" {
- # find .aux and open base .tex/.ltx
- set base [lindex [split $base_aux "."] 0]
- if [file exists ${base}.tex] {
- set base ${base}.tex
- } elseif [file exists ${base}.ltx] {
- set base ${base}.ltx
- } else {
- error "Base file with name '${base}.xxx' not found."
- }
- openFileQuietly ${base}
-
- # find bibliography, position cursor and add
- endOfBuffer
- if [catch {set pos [search -f 0 "\\bibliography\{" [getPos]]}] {
- # add the environment
- set pos [search -f 0 "\\end\{document\}" [getPos]]
- goto [lindex $pos 0]
- set preinsert "\\bibliography\{"
- set postinsert "\}\r\r"
- } else {
- set preinsert ""
- set postinsert ","
- goto [lindex $pos 1]
- }
- set bibfile [bibPickBibliography 0 \
- "Select a bibliography file to add"]
- insertText "${preinsert}[lindex [split $bibfile "."] 0]${postinsert}"
-
- }
- "Cancel" {
- # nothing
- }
- }
- return
- } else {
- # go to a current entry
- bibGotoEntry $item
- beep
- message "Warning--$warning $item"
- return
- }
- }
- default {
- bib_GotoError $msg
- }
- }
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bib_GotoError" --
- #
- # Parse and goto a specific error in a particular file. Look locally for
- # the correct text in case we've edited the file.
- # -------------------------------------------------------------------------
- ##
- proc bib_GotoError {msg} {
- # it's an error. Extract type, line, filename, and position of error
- set errtype [lindex [split $msg "-"] 0]
- if ![regsub {.*line ([0-9]+) .*} $msg {\1} line] {
- error "Failed to parse line number from BibTeX error"
- }
- if ![regsub {.*of file (.*) a .*} $msg {\1} filename] {
- error "Failed to parse filename from BibTeX error"
- }
- if ![regsub {.*a '(.*)' at.*} $msg {\1} problem] {
- error "Failed to parse filename from BibTeX error"
- }
- if ![regsub {.*at (.*)} $msg {\1} linepos] {
- error "Failed to parse line position from BibTeX error"
- }
- openTeXFile $filename
- goto [rowColToPos $line $linepos]
- # Un-map the encoding we did on the other end.
- regsub "‘" $problem "\{" problem
- regsub "’" $problem "\}" problem
- # Un-map the encoding we did on the other end.
- regsub "‘" $errtype "\{" errtype
- regsub "’" $errtype "\}" errtype
- set pos [getPos]
- set t [getText [lineStart $pos] $pos]
- if {$t != $problem} {
- # we've edited the file; look locally
- set pr "^[quoteExpr2 $problem]"
- if {![catch {search -f 0 -r 1 -l [expr $pos - 300] $pr $pos} found]} {
- set pos [lindex $found 1]
- } elseif {![catch {search -f 1 -r 1 -l [expr $pos + 300] $pr $pos} found]} {
- set pos [lindex $found 1]
- }
- }
- select [lineStart $pos] $pos
- beep
- message "$errtype"
- return
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "TeXEnsureSearchPathSet" --
- #
- # Make sure TeX mode has built our search path, so we can find
- # bibliography files. Perhaps we should have our own variable
- # for these?
- # -------------------------------------------------------------------------
- ##
- proc TeXEnsureSearchPathSet {} {
- global TeXSearchPath
- if { [llength $TeXSearchPath] == 0 } {
- message "building TeX search path…"
- set TeXSearchPath [buildTeXSearchPath]
- message ""
- }
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bibPickBibliography" --
- #
- # Put up a list-dialog so the user can select a bibliography file for
- # some action (taken by the caller). Can also create a new file if
- # desired.
- # -------------------------------------------------------------------------
- ##
- proc bibPickBibliography {{allowNew 1} {prompt "Pick a bibliography file"}} {
- set biblist [bibListAllBibliographies]
- if $allowNew {
- lappend biblist {New file…}
- }
- set bibfile [listpick -p $prompt $biblist]
- if {$bibfile == ""} {
- error "No bibliography file selected."
- } elseif {$bibfile == "New file…" } {
- set bibfile [putfile "Save new bibliography as…" ".bib"]
- if {$bibfile == ""} {
- error "No bibliography file selected."
- } else {
- set fout [open $bibfile w]
- close $fout
- }
- }
- return [file tail $bibfile]
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bibListAllBibliographies" --
- #
- # Return all bibliographies on the search path.
- # -------------------------------------------------------------------------
- ##
- proc bibListAllBibliographies {} {
- TeXEnsureSearchPathSet
- global TeXSearchPath
- foreach f $TeXSearchPath {
- eval lappend biblist [glob -nocomplain ${f}*.bib]
- }
- return $biblist
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bibGotoEntry" --
- #
- # Look for a bib entry in the given list of files, or if that fails or
- # isn't given, look in all available bib files on the search path.
- # -------------------------------------------------------------------------
- ##
- proc bibGotoEntry {entry {biblist {}}} {
- if ![catch {bib_GotoEntryFromIndex $entry}] {
- return
- }
- if {[llength $biblist] && ![catch {bib_GotoEntry $entry $biblist}]} {
- return
- }
- if ![catch {bib_GotoEntry $entry [bibListAllBibliographies]}] {
- return
- }
- beep
- error "Can't find entry '$entry' in the .bib file(s)"
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bib_GotoEntryFromIndex" --
- #
- # Look in the bibIndex and find an entry very quickly.
- # -------------------------------------------------------------------------
- ##
- proc bib_GotoEntryFromIndex {entry} {
- set bibTopPat {@([a-zA-Z]+)[\{\(][ ]*}
- global PREFS
- # if it fails, but we succeed later, we will have the opportunity
- # to rebuild the bibIndex
- if [file exists "${PREFS}:bibIndex"] {
- source "${PREFS}:bibIndex"
- global bibIndex
- foreach f [array names bibIndex] {
- if [regexp "\[ \r\n\]$entry\[ \r\n\]" "$bibIndex($f)"] {
- openFileQuietly $f
- set p [search -f 1 -r 1 $bibTopPat$entry 0]
- eval select $p
- centerRedraw
- eval select $p
- unset bibIndex
- return
- }
- }
- unset bibIndex
- }
- error "Entry '$entry' not found in bibIndex"
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bib_GotoEntry" --
- #
- # Find a bib entry in one of the given list of files, and signal an
- # error if the entry isn't found. I think this is the quickest way.
- # -------------------------------------------------------------------------
- ##
- proc bib_GotoEntry {entry biblist} {
- set bibTopPat {@([a-zA-Z]+)[\{\(][ ]*}
- set cid [scancontext create]
- scanmatch $cid $bibTopPat$entry {
- set found "$matchInfo(subindex0)"
- }
- set found ""
- foreach f $biblist {
- message "Searching [file tail $f]…"
- if {![catch {set fid [open $f]}]} {
- scanfile $cid $fid
- close $fid
- if {$found != ""} {
- openFileQuietly $f
- eval select $found
- scancontext delete $cid
- global bib_AutoIndex
- # make the index since it was obviously out of date
- if {$Bib_AutoIndex == 2 || [askyesno "The bibIndex is obviously out of date. Rebuild?"]=="yes"} {
- bib_MakeIndex
- }
- return
- }
- }
- }
- scancontext delete $cid
- error "Entry '$entry' not found."
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bib_MakeIndex" --
- #
- # Build the bibIndex file which allows for very fast lookup of bib
- # entries.
- # -------------------------------------------------------------------------
- ##
- proc bib_MakeIndex {} {
- global PREFS
- set bibTopPat2 {^[ ]*@([a-zA-Z]+)[\{\(][ ]*([^=, ]+)}
- set cid [scancontext create]
- # this will actually mark strings as well
- scanmatch $cid $bibTopPat2 {
- if {[string tolower $matchInfo(submatch0)] != "string"} {
- lappend found $matchInfo(submatch1)
- }
- }
- set bout [open "${PREFS}:bibIndex" w]
- puts $bout "# Bibliography index file for quick reference lookup"
- puts $bout "# Created on [mtime [now]]"
- foreach f [bibListAllBibliographies] {
- set found {}
- puts $bout "set \"bibIndex($f)\" \{"
- message "Scanning [file tail $f]…"
- if {![catch {set fid [open $f]}]} {
- scanfile $cid $fid
- close $fid
- }
- puts $bout $found
- puts $bout "\}"
- }
- close $bout
- scancontext delete $cid
- message "bibIndex creation complete"
- }
-